Skip to content

feat(psychometric): restore Driver 2017-era T0TOTALVAR extra+p_0 on main - #324

Draft
seonghobae wants to merge 2 commits into
mainfrom
agent/psychometric-t0-total-var-on-main
Draft

seonghobae wants to merge 2 commits into
mainfrom
agent/psychometric-t0-total-var-on-main

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Outcome

Restores the executable Driver, Oud, and Voelkle (2017) 2017-era T0TOTALVAR scalar t0_trait² · trait + p_0 on current main after 0ce16e8 dropped the pre-consolidation code while research notes already named later Driver maps (register items 110–111).

Independent of open #322 T0TRAITVARstd, #321 unstandardised T0TRAITVAR, #320 Eq. 5 of T0TRAITEFFECT carry, #319 T0TRAITEFFECT carry, #318 T0TRAITEFFECT, #317 T0TDPREDCOV, #316 LAMBDAstd, #315/#272 TIPREDVARstd, #314 DRIFTstd, #313 DIFFUSIONstd, #312 Kish-weighted CWC, #311 discreteDIFFUSIONstd, #310 discreteDRIFTstd, #309 Eq. 5 of addedTIPREDVAR, #308 Eq. 5 of addedT0TIPREDVAR, #307 addedT0TIPREDVAR, #306 addedTIPREDVARstd, #305 discreteTIPREDEFFECTstd, #304 TDPREDEFFECTstd, #303 T0TDPREDEFFECTstd, #302 T0TIPREDEFFECTstd, #300 TIPREDEFFECTstd, and #299 asymTIPREDEFFECTstd. Do not stack on those PRs. This crate does not currently export recover_initial_trait_variance; form the quadratic extra inline, then add free first-occasion T0VAR.

JSS PDF re-opened 2026-08-30T18:50Z from https://www.jstatsoft.org/index.php/jss/article/download/v077i05/1104. Table 2 (p. 12 TRAITVAR / T0VAR), §7.1 (pp. 18–19), and p. 16 were read from that PDF. 2017-era ctsem 2.5.0 summary.ctsemFit.R (lines 322–339) was re-read locally.

  • Table 2 names TRAITVAR φ_ξ the latent trait variance/covariance and T0VAR the latent process initial variance/covariance. Section 7.1 names traits the stable between-subject differences (unit-level unobserved heterogeneity).
  • T0TRAITEFFECT is not in Table 2 or Table 3. The 2017-era summary.ctsemFit.R (lines 322–331) comments T0TRAITVAR <- T0TRAITEFFECT %*% TRAITVAR %*% t(T0TRAITEFFECT) with #is this valid?.
  • Line 339 then forms T0TOTALVAR <- T0TRAITVAR + T0VAR.
  • The scalar analog extra is t0_trait² · trait. The scalar total is extra + p_0.
  • Form the extra first, then add free p_0. A zero extra or zero p_0 is kept. A zero extra and a zero p_0 is exactly zero.
  • trait < 0 or p_0 < 0 fails closed. T0 is an event-time occasion, so a non-event clock fails closed. An overflowing product or sum fails closed.
  • Free T0TRAITEFFECT and free T0VAR do not require stable a < 0.
  • t0_trait² · trait is T0TRAITVAR and equals this total when p_0 = 0 and remains a distinct named quantity.
  • Free p_0 is T0VAR and equals this total when the extra is 0 and remains a distinct named quantity.
  • TRAITVAR equals this total when T0TRAITEFFECT = I and p_0 = 0 and remains a distinct named quantity.
  • t0_b² v is addedT0TIPREDVAR and is extra first-occasion TI variance, not this total.

Meredith (1993) remains unread (Unpaywall 2026-08-30T18:40Z: is_oa: false; OpenAlex closed; Springer content/pdf is an HTML stub). Mislevy (1991, Psychometrika, 56, 177–196) remains unread on the same terms (DOI 10.1007/bf02294457).

Still not a Kalman filter, not a matrix expm, not ESEM estimation, not DSEM, and not ctsem estimation.

Local cargo test -p psychometric_core: 189 lib tests, 110 multilevel tests, 53 scientific-claim tests, plus crate/ESEM/plausible/Rubin contracts, all passed. cargo clippy -p psychometric_core --all-targets -- -D warnings passed.

Do not squash-merge without independent non-author APPROVE plus exact-head required-check success. Do not self-approve. Do not wait on Checks for this or sibling psychometric PRs.

Scalar analog of T0TRAITVAR+T0VAR from commented 2017-era
summary.ctsemFit.R (ctsem 2.5.0 line 339). Form t0_trait² · trait
inline; do not import unpublished recover_initial_trait_variance.
Independent of #321/#322. Zero extra or zero p_0 is kept; 0+0=0.
Refuse T0TRAITVAR, T0VAR, TRAITVAR, and addedT0TIPREDVAR t0_b² v.
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor Author

Independent review only. Please review this head (c9b3e6e) as Driver 2017-era T0TOTALVAR t0_trait² · trait + p_0 (ctsem 2.5.0 summary.ctsemFit.R line 339). Independent of #321/#322. Form extra inline; do not import unpublished recover_initial_trait_variance. Do not APPROVE as the author.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Exact head and PR diff summary =='
git rev-parse HEAD
git status --short
git diff --stat HEAD^ HEAD
git diff --name-only HEAD^ HEAD

printf '%s\n' '== Changed-file outlines =='
git diff --name-only HEAD^ HEAD | while IFS= read -r file; do
  case "$file" in
    *.rs)
      printf '\n-- %s --\n' "$file"
      ast-grep outline "$file" --items all || true
      ;;
  esac
done

printf '%s\n' '== Full PR diff =='
git diff --find-renames --find-copies --unified=80 HEAD^ HEAD

printf '%s\n' '== Relevant definitions and uses =='
rg -n -i -C 5 \
  't0totalvar|t0_trait|t0var|traitvar|recover_initial_trait_variance|event.time|event_time|is_finite|finite' \
  --glob '*.rs' .

Length of output: 200833


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="crates/psychometric_core/src/event_time.rs"

printf '%s\n' '== Commit metadata and changed paths =='
git show --no-patch --format='commit=%H%nparents=%P%nsubject=%s' HEAD
git diff-tree --no-commit-id --name-status -r HEAD

printf '%s\n' '== Exact patch for T0TOTALVAR symbols =='
git diff --unified=25 HEAD^ HEAD -- "$file" | \
  grep -n -E -C 20 'recover_initial_total_variance|InitialTotalVariance|T0TOTALVAR|recover_initial_trait_variance' || true

printf '%s\n' '== Implementation, refusal functions, and tests =='
sed -n '6790,6940p' "$file"
sed -n '16470,16680p' "$file"

printf '%s\n' '== Symbol definitions and crate exports =='
rg -n -C 4 \
  'recover_initial_total_variance|InitialTotalVarianceIsNot|recover_initial_trait_variance' \
  --glob '*.rs' crates/psychometric_core

printf '%s\n' '== Error enum declarations and display/source handling =='
rg -n -C 3 \
  'InitialTotalVarianceIsNot|enum PsychometricError|match self' \
  --glob '*.rs' crates/psychometric_core

printf '%s\n' '== All new tests in this commit =='
git diff --unified=3 HEAD^ HEAD -- "$file" | \
  grep -n -E -C 8 '^\+.*(fn |recover_initial_total_variance|InitialTotalVariance)' || true

Length of output: 109805


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Focused diffs outside the primary implementation =='
for file in \
  ARCHITECTURE.md CHANGELOG.md CLAUDE.md docs/TRACEABILITY.md \
  docs/adr/0005-posterior-esem-dsem.md \
  docs/research/multilevel-event-time-recovery.md \
  crates/psychometric_core/src/lib.rs \
  crates/psychometric_core/src/error.rs \
  crates/psychometric_core/tests/multilevel_event_time_recovery_contract.rs \
  crates/psychometric_core/tests/scientific_claim_boundary_contract.rs
do
  printf '\n-- %s --\n' "$file"
  git diff --unified=12 HEAD^ HEAD -- "$file" | \
    grep -n -E -C 12 'T0TOTALVAR|recover_initial_total_variance|InitialTotalVariance|recover_initial_trait_variance|^\+' || true
done

printf '%s\n' '== Public re-exports of the new boundary helpers =='
rg -n -C 2 'refuse_initial_total_variance' crates/psychometric_core/src/lib.rs

printf '%s\n' '== Explicit sum-overflow coverage =='
rg -n -C 3 \
  'recover_initial_total_variance\([^)]*(MAX|1e308)|initial_total_variance.*overflow|extra.*initial_variance.*overflow' \
  --glob '*.rs' crates/psychometric_core

printf '%s\n' '== Static arithmetic checks for required boundary cases =='
python3 - <<'PY'
import math
cases = {
    "square_overflow": (1e200, 1.0, 1.0),
    "extra_product_overflow": (1e154, 1e2, 0.0),
    "final_sum_overflow": (1.0, float.fromhex("0x1.fffffffffffffp+1023"), float.fromhex("0x1.fffffffffffffp+1023")),
}
for name, (effect, trait, p0) in cases.items():
    squared = effect * effect
    extra = squared * trait
    total = extra + p0
    print(f"{name}: squared_finite={math.isfinite(squared)} extra_finite={math.isfinite(extra)} total_finite={math.isfinite(total)}")
PY

Length of output: 199064


@seonghobae Review complete for head c9b3e6e.

I found no blocking defect in the inspected implementation.

  • recover_initial_total_variance computes t0_trait² · trait inline, then adds p_0.
  • It does not import or call recover_initial_trait_variance.
  • It rejects non-event clocks, non-finite inputs, negative trait or p_0, and non-finite intermediate products or final sums.
  • The public API and the new boundary errors are exported and covered by unit and integration tests.
  • The code does not require stable a < 0.

Non-blocking test gap: add a case where extra and p_0 are each finite but extra + p_0 overflows. The final require_finite(extra + initial_variance) guard is present.

I did not approve the PR.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Resolve the CHANGELOG.md append conflict by keeping both entries.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@seonghobae

Copy link
Copy Markdown
Contributor Author

Restack on protected main (a243f18)

Non-force merge of origin/main (merge commit a1b32089); the only conflict was the CHANGELOG.md append, both entries kept.

Local evidence on the pushed head (toolchain 1.98.0): cargo test -p psychometric_core 369 passed / 0 failed, clippy -D warnings clean, cargo fmt --all --check clean, documentation/workspace/docstring contracts PASS, git diff --check clean.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request priority: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant